/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package assisisw.smartcal.webuisubsystem.managedbean.event;

import assisisw.smartcal.entitysubsystem.Calendar;
import assisisw.smartcal.entitysubsystem.Event;
import assisisw.smartcal.entitysubsystem.IEventController;
import assisisw.smartcal.entitysubsystem.IUserController;
import assisisw.smartcal.entitysubsystem.User;
import assisisw.smartcal.entitysubsystem.exceptions.user.UserNotRegisteredException;
import assisisw.smartcal.timeconsistencysubsystem.ITimelineVerifier;
import assisisw.smartcal.weathersubsystem.IRealTimeDataProvider;
import assisisw.smartcal.weathersubsystem.WeatherData;
import assisisw.smartcal.webuisubsystem.managedbean.DashboardBean;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import static javax.faces.context.FacesContext.getCurrentInstance;
import org.primefaces.context.RequestContext;
import org.primefaces.event.SelectEvent;

/**
 *
 * @author Francesco
 */
public abstract class AbstractEventControllerBean implements Serializable 
{
    
    private List < String > visibilities ;
    
    /***/
    public List < String > getVisibilities () 
    {
        return visibilities ;
    }
  
    // Instance Fields
    
    /***/
    @EJB
    private IUserController userController ;
    
    /***/
    @EJB ()
    private IEventController eventController ;
    
    /***/
    @EJB ()
    private IRealTimeDataProvider realTimeDataProvider ;
    
    /***/
    @EJB ()
    private ITimelineVerifier timelineVerifier ;
    
    /***/
    private List < Calendar > availableCalendars ;
    
    /***/
    private Event managedEvent ;
    
    /***/
    private String newSharedMail ;
    
    /***/
    private String timeConsistencyInfo ;
    
    /***/
    private Integer selectedCalendarId ;
    
    /***/
    private boolean weatherInfoAvailable ;    
    
    /***/
    private boolean editAllowed ;
    
    // Instance Methods
    
    /***/
    public AbstractEventControllerBean () {}
    
    /***/
    public abstract void confirmAction () ;
    
    /***/
    public abstract void undoAction () ;
    
    /***/
    public void newShareAction () 
    {
        Event thisEvent ;
        User selectedUser ;
        if ( userController.isRegistered ( getNewSharedMail() ) )
        {
            try 
            {
                thisEvent = getManagedEvent () ;
                selectedUser = userController.getUser( getNewSharedMail () ) ;
                if ( ! selectedUser.equals ( getDashboardBean().getManagedUser () ) )
                {
                    if ( ! thisEvent.getInvitedUsers().contains ( selectedUser ) )
                    {
                        // he is ok, no mail for him
                        effectiveSharing ( selectedUser ) ; 
                        setNewSharedMail ( "" ) ;
                        FacesContext.getCurrentInstance().addMessage ( null , new FacesMessage ( "Done !" ) ) ;
                    }
                    else
                    {
                        FacesContext.getCurrentInstance().addMessage ( null , new FacesMessage ( "Already Invited !" ) ) ;
                        // no double sharing allowed
                    }
                }
                else
                {
                    FacesContext.getCurrentInstance().addMessage ( null , new FacesMessage ( "No self-invitation !" ) ) ;
                    // no self sharing allowed
                }
            } 
            catch (UserNotRegisteredException ex) 
            {
                // problems
            }
        }
        else
        {
            FacesContext.getCurrentInstance().addMessage ( null , new FacesMessage ( "Sorry he is not in SmartCAL !" ) ) ;            
            // not registered, we should send him an email and manage this
        }
    }
    
    /***/
    public void deleteAction () {}
    
    protected abstract void effectiveSharing ( User u ) ;
    
    /***/
    @PostConstruct 
    public void init () 
    {
        availableCalendars = new ArrayList <> () ;
        visibilities = new ArrayList<>(2);
        visibilities.add(Event.PUBLIC_VISIBILITY);
        visibilities.add(Event.PRIVATE_VISIBILITY);
        editAllowed = true ;
        timeConsistencyInfo = "" ;
    }
    
    /**
     * @return
     */
    public List < Calendar > getAvailableCalendars () 
    {
        return availableCalendars ;
    }
    
    /**
     * @param availableCalendars 
     */
    public void setAvailableCalendars ( List < Calendar > availableCalendars ) 
    {
        this.availableCalendars = availableCalendars ;
    }
    
    /**
     * @param managedEvent 
     */
    public void setManagedEvent ( Event managedEvent ) 
    {
        this.managedEvent = managedEvent ;
    }
    
    /** 
     * @return
     */
    public Event getManagedEvent () 
    {
        return managedEvent ;
    }
    
    /**
     * @param newSharedMail 
     */
    public void setNewSharedMail ( String newSharedMail ) 
    {
        this.newSharedMail = newSharedMail ;
    }
    
    /**
     * @return
     */
    public String getNewSharedMail () 
    {
        return newSharedMail ;
    }
    
    public void setTimeConsistencyInfo ( String timeConsistencyInfo ) 
    {
        this.timeConsistencyInfo = timeConsistencyInfo ;
    }
    
    public String getTimeConsistencyInfo () 
    {
        return timeConsistencyInfo ;
    }
    
    /**
     * @param selectedCalendarId
     */
    public void setSelectedCalendarId ( Integer selectedCalendarId ) 
    { 
        this.selectedCalendarId = selectedCalendarId ;
    }
    
    /**
     * @return
     */
    public Integer getSelectedCalendarId () 
    {
        return selectedCalendarId ;
    }
    
    /**
     * @param weatherInfoAvailable  
     */
    public void setWeatherInfoAvailable ( boolean weatherInfoAvailable ) 
    {
        this.weatherInfoAvailable = weatherInfoAvailable ;
    }
    
    /**
     * @return
     */
    public boolean isWeatherInfoAvailable () 
    {
        return weatherInfoAvailable ;
    }
    
    /**
     * @param editAllowed 
     */
    public void setEditAllowed ( boolean editAllowed ) 
    {
        this.editAllowed = editAllowed ;
    }
    
    /**
     * @return
     */
    public boolean isEditAllowed () 
    {
        return editAllowed ;
    }
    
    public void onDateSelected ( SelectEvent selectEvent ) 
    {
        Collection res ;
        res = timelineVerifier.verify ( getDashboardBean().getManagedUser() , managedEvent ) ;
        if ( res.size() > 0 )
        {
            timeConsistencyInfo = "Attention, you have some other events already registered this time !" ;
            RequestContext.getCurrentInstance().update("timeConsistencyText");
        }
    }
    
    /***/
    public void updateWeather () 
    {
        WeatherData weatherData;
        String location ;
        location = managedEvent.getPlace () ;
        weatherData = realTimeDataProvider.extract(location);
        if ( weatherData != null )
        {
            managedEvent.setWeatherInfo ( String.format ( "%s C, %s" , weatherData.getTemeperature() , weatherData.getDescription () ) ) ;
            weatherInfoAvailable = true ;
        }
    }
    
    /**
     * @return
     */
    protected IEventController getEventController () 
    {
        return eventController ;
    }
    
    /**
     * @return
     */
    protected DashboardBean getDashboardBean () 
    {
        DashboardBean dashboardBean ;
        dashboardBean = getCurrentInstance().getApplication().evaluateExpressionGet(FacesContext.getCurrentInstance(), "#{dashboardBean}",DashboardBean.class);
        return dashboardBean ;
    }
    
    /**
     * @return 
     */
    protected Calendar getSelectedCalendar () 
    {
        Calendar res ;
        res = null ;
        if ( selectedCalendarId != null )
            for ( Calendar c : availableCalendars )
                if ( c.getId ().intValue () == selectedCalendarId.intValue () )
                {
                    res = c ;
                    break ;
                }
        return res ;
    }
    
    /**
     * @return
     */
    protected boolean isTimelineSafe () 
    {
        boolean res ;
        res = timelineVerifier.verify ( getDashboardBean().getManagedUser () , managedEvent ).isEmpty () ;
        return res ;
    }
    
}
